﻿using System;

namespace AntBot
{
	public class IOManager
	{
		public bool EndOfGame { get; private set; }

		private static string ReadLine()
		{
			int c;
			string line = "";

			while ((c = Console.Read()) >= 0)
			{
				switch (c)
				{
					case '\n': return line.ToLower();
					case '\r': break;
					default:
						line += (char)c;
						break;
				}
			}
			return line.ToLower();
		}

		internal static void ParseSettingsLine(string line, Settings settings)
		{
			string[] tokens = line.ToLower().Split(' ');
			if (tokens[0] == "cols") settings.Cols = int.Parse(tokens[1]);
			else if (tokens[0] == "rows") settings.Rows = int.Parse(tokens[1]);
			else if (tokens[0] == "turns") settings.Turns = int.Parse(tokens[1]);
			else if (tokens[0] == "loadtime") settings.LoadTime = int.Parse(tokens[1]);
			else if (tokens[0] == "turntime") settings.TurnTime = int.Parse(tokens[1]);
			else if (tokens[0] == "viewradius2") settings.ViewRadius2 = int.Parse(tokens[1]);
			else if (tokens[0] == "attackradius2") settings.AttackRadius2 = int.Parse(tokens[1]);
			else if (tokens[0] == "spawnradius2") settings.SpawnRadius2 = int.Parse(tokens[1]);
		}

		internal static void ParseTurnLine(string line, DataSet dataSet)
		{
			Logger.Log(line);
			string[] tokens = line.ToLower().Split(' ');

			if (tokens[0] == "turn")
			{
				dataSet.TurnNumber = int.Parse(tokens[1]);
				return;
			}

			if (tokens.Length < 3)
				throw new IndexOutOfRangeException("Неверная входная строка: " + line);

			int row = int.Parse(tokens[1]);
			int col = int.Parse(tokens[2]);

			int owner = 0;
			if (tokens.Length > 3)
				owner = int.Parse(tokens[3]) + State.MY_ANT;

			Location location = new Location(col, row);

			if (tokens[0] == "a") dataSet.Ants.Add(new Pair<Location, int>(location, owner));
			//if (tokens[0] == "d") dataSet.DeadAnts.Add(location);
			if (tokens[0] == "f") dataSet.Food.Add(location);
			if (tokens[0] == "w") dataSet.Water.Add(location);
		}

		public Settings ReadSettings()
		{
			Settings settings = new Settings();

			do
			{
				string line = ReadLine();
				if (line == "ready") return settings;
				ParseSettingsLine(line, settings);
			} while (true);
		}

		public DataSet ReadTurn()
		{
			DataSet dataSet = new DataSet();
			do
			{
				string line = ReadLine();
				if (!EndOfGame)
					EndOfGame = line.ToLower() == "end";

				if (EndOfGame)
					return dataSet;

				if (line == "go") 
					return dataSet;
				ParseTurnLine(line, dataSet);
			} while (true);
		}

		public void SendReady()
		{
			Console.Write("go\n");
			Logger.Log("go");
		}

		public void SendStep(Step step)
		{
			if (step.Direction == State.Directions.Unknown)
				throw new IndexOutOfRangeException("Неправильное направление движения: " + step.Direction);

			string message =
				"o " +
				step.Location.Row +
				" " +
				step.Location.Col +
				" " +
				State.CDIRECTIONS[(int)step.Direction];
			Console.Write(message + "\n");
			Logger.Log(message);
		}
	}
}
